package com.baofu.paycore.manager.storer;

import com.baofu.paycore.common.utils.Validate;
import com.baofu.paycore.dal.model.base.BaseDO;
import com.baofu.paycore.manager.model.PayBaseBO;
import com.baofu.paycore.manager.storage.Storage;
import com.baofu.paycore.manager.storage.StorageContainer;
import com.system.commons.exception.BizServiceException;
import com.system.commons.exception.CommonErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

/**
 * 持久化服务父类
 *
 * <p/>
 *      1、持久化服务
 * </p>
 * User: LZQ Date: 2016/04/20  Version: 1.0
 */
@Slf4j
@Component
public abstract class AbstractOrderRepository<T extends PayBaseBO> implements OrderRepository<T> {

    private static final int add = 1;
    private static final int update = 2;
    private static final int delete = 3;

    /**
     * 存储容器
     */
    @Autowired
    private StorageContainer container;

    /**
     * 持久化处理
     *
     * @param payBaseBO    订单对象
     * @param operate      操作类型
     */
    private void operate(T payBaseBO,int operate){
        payBaseBO.checkStatus();
        List<? extends BaseDO> payModels = convertToDO(payBaseBO);
        for(BaseDO model: payModels){
            doOperate(operate,model,container.getStore(model));
        }
    }

    /**
     * 订单转换
     *
     * @param payBaseBO    支付对象
     * @return             转换后DO
     */
    protected abstract List<? extends BaseDO> convertToDO(T payBaseBO) ;

    /**
     * 操作类型
     *
     * @param operate    操作类型
     * @param object     模型
     * @param storage    仓储对象
     */
    private int doOperate(int operate, BaseDO object,Storage storage) {
        int result;
        switch (operate) {
            case add:
                result = storage.addOrder(object);
                break;
            case update:
                result = storage.modifyOrder(object);
                break;
            case delete:
                result = storage.deleteOrder(object);
                break;
            default:
                log.error("无法识别的仓储操作:{}",operate);
                throw new BizServiceException(CommonErrorCode.SYSTEM_INNER_ERROR,"无法识别的仓储操作");
        }
        Validate.checkUpdate(result);
        return result ;
    }

    /**
     * 新增订单
     *
     * @param payBaseBO 订单信息
     */
    @Transactional(isolation = Isolation.DEFAULT,
            propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void addOrder(T payBaseBO) {
        operate(payBaseBO,add);
    }

    /**
     * 更新订单
     *
     * @param payBaseBO 订单信息
     */
    @Transactional(isolation = Isolation.DEFAULT,
            propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void update(T payBaseBO) {
        operate(payBaseBO,update);
    }

    /**
     * 废弃订单
     *
     * @param payBaseBO 订单信息
     */
    @Transactional(isolation = Isolation.DEFAULT,
            propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void destroy(T payBaseBO) {
        operate(payBaseBO,delete);
    }
}
